package com.hc.likelistenmusic.activity

import android.annotation.SuppressLint
import android.app.Dialog
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.telephony.TelephonyManager
import android.text.InputType
import android.text.TextUtils
import android.text.method.TextKeyListener
import android.view.KeyEvent
import android.view.WindowManager
import android.view.animation.AnimationUtils
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.RemoteViews
import android.widget.TextView
import android.widget.Toast
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.hc.likelistenmusic.R
import com.hc.likelistenmusic.bean.OnlineMusicId
import com.hc.likelistenmusic.bean.OnlineMusicResponse
import com.hc.likelistenmusic.config.NotificationPlayStatus
import com.hc.likelistenmusic.fragment.LazyFragment
import com.hc.likelistenmusic.fragment.OnlineLrcFragment
import com.hc.likelistenmusic.fragment.OnlineMusicFragment
import com.hc.likelistenmusic.presenter.OnlineMusicPresenter
import com.hc.likelistenmusic.receiver.NotificationClickJumpTopActivityReceiver
import com.hc.likelistenmusic.util.LrcUtil
import com.hc.likelistenmusic.util.OkHttpUtil
import com.hc.likelistenmusic.util.OkHttpUtil.ResultCallback
import com.hc.likelistenmusic.util.ScreenUtil
import com.hc.likelistenmusic.view.CommonDialog
import com.hc.likelistenmusic.view.RoundRotateProgressView
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer

class OnlineMusicActivity : AppCompatActivity() {
    val TAG = "HUACHEN_OnlineMusicActivity"
    lateinit var mOnlineMusicPresenter: OnlineMusicPresenter
    lateinit var mComeInPhoneReceiver: ComeInPhoneReceiver
    lateinit var mVp_aom:ViewPager2
    lateinit var mIv_aom_back:ImageView
    lateinit var mIv_aom_clear:ImageView
    lateinit var mIv_aom_search_cancel:ImageView
    lateinit var mIv_aom_search:ImageView
    lateinit var mIv_aom_play:ImageView
    lateinit var mIv_aom_pre:ImageView
    lateinit var mIv_aom_next:ImageView
    lateinit var mRrpv_aom:RoundRotateProgressView
    lateinit var mTv_aom_musicInfo:TextView
    lateinit var mTv_aom_musicDuration:TextView
    lateinit var mEt_aom_search:EditText
    lateinit var mVp_aom_adapter_fragments: MutableList<LazyFragment>
    lateinit var mBackDialog: CommonDialog
    lateinit var mInfoDialog: CommonDialog
    var mNotificationManager: NotificationManager? = null
    var mNotificationActionReceiver: NotificationActionReceiver? = null
    var mRemoteView: RemoteViews? = null
    var mNotification: Notification? = null
    val mNotificationId = 2
    var mIsRingLing = false
    var mIsHandControl = false
    var mOnlineMusicId: OnlineMusicResponse ?=null
    var mExitTime = -1L
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val window = window
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
        window.statusBarColor = resources.getColor(R.color.color_theme)
        window.navigationBarColor = resources.getColor(R.color.color_theme)
        setContentView(R.layout.activity_online_music)

        mOnlineMusicPresenter = OnlineMusicPresenter(this)
        initViews()
        registerComeInPhoneReceiver()
        generateNotification()
    }

    private fun initViews() {
        mVp_aom_adapter_fragments = mutableListOf()
        mVp_aom_adapter_fragments.add(OnlineMusicFragment())
        mVp_aom_adapter_fragments.add(OnlineLrcFragment())
        val mSvp_aom: StandardGSYVideoPlayer = findViewById(R.id.svp_aom)
        mOnlineMusicPresenter.setVideoPlayer(mSvp_aom)
        mIv_aom_back = findViewById(R.id.iv_aom_back)
        mIv_aom_clear = findViewById(R.id.iv_aom_clear)
        mIv_aom_search_cancel = findViewById(R.id.iv_aom_search_cancel)
        mIv_aom_search = findViewById(R.id.iv_aom_search)
        mIv_aom_play = findViewById(R.id.iv_aom_play)
        mIv_aom_pre = findViewById(R.id.iv_aom_pre)
        mIv_aom_next = findViewById(R.id.iv_aom_next)
        mRrpv_aom = findViewById(R.id.rrpv_aom)
        mRrpv_aom.setBimap(BitmapFactory.decodeResource(resources, R.drawable.app_logo))
        mTv_aom_musicInfo = findViewById(R.id.tv_aom_musicInfo)
        mTv_aom_musicDuration = findViewById(R.id.tv_aom_musicDuration)
        mEt_aom_search = findViewById(R.id.et_aom_search)
        mVp_aom = findViewById(R.id.vp_aom)
        mVp_aom.apply {
            val rv = getChildAt(0)
            if(rv is RecyclerView){
              rv.overScrollMode = ViewPager2.OVER_SCROLL_NEVER
            }
            orientation = ViewPager2.ORIENTATION_HORIZONTAL
            offscreenPageLimit = 1
            adapter = object : FragmentStateAdapter(this@OnlineMusicActivity){
                override fun getItemCount(): Int {
                    return mVp_aom_adapter_fragments.size
                }

                override fun createFragment(position: Int): Fragment {
                    return mVp_aom_adapter_fragments.get(position)
                }
            }
        }
        mBackDialog = CommonDialog.Builder()
            .setContext(this)
            .setLayoutId(R.layout.dialog_back)
            .setLeftViewId(R.id.negative)
            .setRightViewId(R.id.positive)
            .setCancelable(false)
            .setDefaultListener(object : CommonDialog.CommonDialogDefaultOnClickListener {
                override fun onLeftViewClick(dialog: Dialog?) {
                    dialog?.dismiss()
                    MediaPlay()
                }

                override fun onCommonViewClick(dialog: Dialog?) {

                }

                override fun onRightViewClick(dialog: Dialog?) {
                    dialog?.dismiss()
                    val intent = Intent(this@OnlineMusicActivity, SplashActivity::class.java)
                    intent.putExtra("mBack",true)
                    startActivity(intent)
                    finish()
                }

            }).build()
        mInfoDialog = CommonDialog.Builder()
            .setContext(this)
            .setLayoutId(R.layout.dialog_info)
            .setCancelable(false)
            .build()
        mIv_aom_search.setOnClickListener {
            onSearchOrCancelClick(true)
        }
        mIv_aom_search_cancel.setOnClickListener {
            onSearchOrCancelClick(false)
        }
        mIv_aom_clear.setOnClickListener {
            onClearClick()
        }
        mIv_aom_back.setOnClickListener {
            onBackClick()
        }
        mIv_aom_play.setOnClickListener {
            onPlayClick()
        }
        mIv_aom_pre.setOnClickListener {
            handChangeNextSong(false)
        }
        mIv_aom_next.setOnClickListener {
            handChangeNextSong(true)
        }
        mEt_aom_search.keyListener = object : TextKeyListener(Capitalize.NONE, false) {
            override fun getInputType(): Int {
                return InputType.TYPE_MASK_CLASS
            }
        }
        mEt_aom_search.setOnEditorActionListener(object : TextView.OnEditorActionListener {
            override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    onSearchOrCancelClick(true)
                    return true
                }
                return false
            }
        })
    }

    private fun onPlayClick() {
        if(mOnlineMusicId != null){
            if(MediaPlayOrPauseStatus()){
                MediaPause()
            }else{
                MediaPlay()
            }
        }else{
            handChangeNextSong(true)
        }
    }

    private fun onBackClick() {
        if(!mBackDialog.isShowing){
            mBackDialog.show()
        }
        MediaPause()
    }

    private fun onClearClick() {
        ScreenUtil.hideSoftInput(this,mEt_aom_search)
        mEt_aom_search.setText("")
        mEt_aom_search.clearFocus()
        findOnlineMusicFragment().clearSearchData()
    }

    private fun onSearchOrCancelClick(search: Boolean) {
        ScreenUtil.hideSoftInput(this,mEt_aom_search)
        if(search){
            mEt_aom_search.clearFocus()
            val searchInfo = mEt_aom_search.text
            if (TextUtils.isEmpty(searchInfo)) {
                mEt_aom_search.startAnimation(
                    AnimationUtils.loadAnimation(
                        this,
                        R.anim.shake
                    )
                )
            }else{
                if(!mInfoDialog.isShowing){
                    mInfoDialog.show()
                }
                mInfoDialog.findViewById<TextView>(R.id.tv_di_info).text = resources.getString(R.string.string_searching)
                findOnlineMusicFragment().loadSearchData(searchInfo)
            }
        }else{
            mEt_aom_search.setText("")
            mEt_aom_search.clearFocus()
        }
    }

    private fun registerComeInPhoneReceiver() {
        mComeInPhoneReceiver = ComeInPhoneReceiver()
        IntentFilter().apply {
            priority = Int.MAX_VALUE
            addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
            registerReceiver(mComeInPhoneReceiver, this)
        }
    }

    @SuppressLint("LaunchActivityFromNotification")
    private fun generateNotification() {
        if(!NotificationManagerCompat.from(this).areNotificationsEnabled()){
            return
        }
        mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        mNotificationActionReceiver = NotificationActionReceiver()
        IntentFilter().apply {
            addAction(NotificationPlayStatus.STATUS_PREV)
            addAction(NotificationPlayStatus.STATUS_PLAY_OR_PAUSE)
            addAction(NotificationPlayStatus.STATUS_NEXT)
            addAction(NotificationPlayStatus.STATUS_CLOSE)
            registerReceiver(mNotificationActionReceiver, this)
        }
        mRemoteView = RemoteViews(packageName, R.layout.notification_play_control)
        var prePendingIntent = PendingIntent.getBroadcast(
            applicationContext, 0, Intent(NotificationPlayStatus.STATUS_PREV),
            PendingIntent.FLAG_IMMUTABLE
        )
        var playPendingIntent = PendingIntent.getBroadcast(
            applicationContext, 0, Intent(NotificationPlayStatus.STATUS_PLAY_OR_PAUSE),
            PendingIntent.FLAG_IMMUTABLE
        )
        var nextPendingIntent = PendingIntent.getBroadcast(
            applicationContext, 0, Intent(NotificationPlayStatus.STATUS_NEXT),
            PendingIntent.FLAG_IMMUTABLE
        )
        var closePendingIntent = PendingIntent.getBroadcast(
            applicationContext, 0, Intent(NotificationPlayStatus.STATUS_CLOSE),
            PendingIntent.FLAG_IMMUTABLE
        )
        mRemoteView?.apply {
            setOnClickPendingIntent(R.id.iv_npc_pre, prePendingIntent)
            setOnClickPendingIntent(R.id.iv_npc_playorpause, playPendingIntent)
            setOnClickPendingIntent(R.id.iv_npc_next, nextPendingIntent)
            setOnClickPendingIntent(R.id.iv_npc_close, closePendingIntent)
        }
        val channelId = "Notification_Play_Control"
        val channelName = "通知栏播放控制"
        val importance = NotificationManager.IMPORTANCE_HIGH
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationChannel(channelId, channelName, importance).apply {
                enableLights(false)
                enableVibration(false)
                vibrationPattern = LongArray(0) { 0 }
                setSound(null, null)
                mNotificationManager?.createNotificationChannel(this)
            }
        }
        mNotification = NotificationCompat.Builder(this, channelId).apply {
            setContentIntent(PendingIntent.getBroadcast(
                applicationContext, 0, Intent(
                    applicationContext,
                    NotificationClickJumpTopActivityReceiver::class.java
                ), PendingIntent.FLAG_UPDATE_CURRENT
            ))
            setWhen(System.currentTimeMillis())
            setSmallIcon(R.drawable.app_logo)
            setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.app_logo))
            setCustomContentView(mRemoteView)
            setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            setAutoCancel(false)
            setOnlyAlertOnce(true)
            setOngoing(true)
        }.build()
    }
    override fun onBackPressed() {
        if(mVp_aom.currentItem != 0){
            mVp_aom.currentItem = 0
        }else{
            if (mExitTime == -1L) {
                mExitTime = System.currentTimeMillis()
                showToast(mOnlineMusicPresenter.getExitInfo())
            } else {
                val currentTimeMillis = System.currentTimeMillis()
                if (currentTimeMillis - mExitTime < 2000) {
                    finish()
                } else {
                    mExitTime = currentTimeMillis
                    showToast(mOnlineMusicPresenter.getExitInfo())
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        if(mIsRingLing){
            MediaPause()
        }else{
            if (!mBackDialog.isShowing) {
                MediaPlay()
            }
        }
    }
    override fun onStop() {
        super.onStop()
        if(mIsRingLing){
            MediaPause()
        }else{
            if (!mBackDialog.isShowing) {
                MediaPlay()
            }
        }
        ScreenUtil.hideSoftInput(this, mEt_aom_search)
    }

    override fun onDestroy() {
        super.onDestroy()
        mNotification?.apply {
            mNotificationManager?.cancel(mNotificationId)
        }
        unregisterReceiver(mComeInPhoneReceiver)
        mNotificationActionReceiver?.let {
            unregisterReceiver(mNotificationActionReceiver)
        }
        mOnlineMusicPresenter.onDestroy()
    }

    fun findOnlineMusicFragment():OnlineMusicFragment{
        return mVp_aom_adapter_fragments.get(0) as OnlineMusicFragment
    }

    fun findOnlineLrcFragment():OnlineLrcFragment{
        return mVp_aom_adapter_fragments.get(1) as OnlineLrcFragment
    }

    fun showToast(info: String) {
        Toast.makeText(applicationContext, info, Toast.LENGTH_SHORT).show()
    }

    fun prepareOnlineMusic(om: OnlineMusicResponse) {
        resetUI()
        if(!mInfoDialog.isShowing){
            mInfoDialog.show()
        }
        mInfoDialog.findViewById<TextView>(R.id.tv_di_info).text = resources.getString(R.string.string_prepareing)
        mOnlineMusicId = om
        mOnlineMusicPresenter.requestOnlineMusicUrl(om)
    }

    fun MediaPlayOrPauseStatus(): Boolean {
        return mOnlineMusicPresenter.MediaPlayOrPauseStatus()
    }

    fun MediaPause() {
        if(mOnlineMusicId != null){
            mIsHandControl = true
            mRrpv_aom.pauseAnim()
            mTv_aom_musicInfo.isSelected = false
            mIv_aom_play.setImageResource(R.drawable.img_play)
            mRemoteView?.setImageViewResource(R.id.iv_npc_playorpause, R.drawable.img_play)
            mRemoteView?.setTextColor(R.id.tv_npc_songinfo, Color.RED)
            if(MediaPlayOrPauseStatus()){
                mOnlineMusicPresenter.MediaPause()
                findOnlineLrcFragment().mLv_fol.setLrcTextColorPlaying(Color.RED)
                mRemoteView?.setTextViewText(
                    R.id.tv_npc_songinfo,
                    "${mOnlineMusicId!!.name} - ${mOnlineMusicId!!.singer}"
                )
            }
            mNotificationManager?.notify(mNotificationId, mNotification)
        }
    }

    fun MediaPlay() {
        if(mOnlineMusicId != null){
            mIsHandControl = false
            mRrpv_aom.startAnim()
            mTv_aom_musicInfo.isSelected = true
            mIv_aom_play.setImageResource(R.drawable.img_pause)
            mRemoteView?.setImageViewResource(R.id.iv_npc_playorpause, R.drawable.img_pause)
            mRemoteView?.setTextColor(R.id.tv_npc_songinfo, Color.GREEN)
            if(!MediaPlayOrPauseStatus()){
                mOnlineMusicPresenter.MediaPlay()
                findOnlineLrcFragment().mLv_fol.setLrcTextColorPlaying(Color.GREEN)
                mRemoteView?.setTextViewText(
                    R.id.tv_npc_songinfo,
                    "${mOnlineMusicId!!.name} - ${mOnlineMusicId!!.singer}"
                )
            }
            mNotificationManager?.notify(mNotificationId, mNotification)
        }
    }

    fun resetUI() {
        mTv_aom_musicInfo.text = resources.getString(R.string.string_fragment_music_info_empty)
        mTv_aom_musicInfo.isSelected = false
        mRemoteView?.setTextViewText(
            R.id.tv_npc_songinfo,
            resources.getString(R.string.string_fragment_music_info_empty)
        )
        mRrpv_aom.error()
        mRemoteView?.setTextColor(R.id.tv_npc_songinfo, Color.WHITE)
        findOnlineLrcFragment().setNoLrcs()
        mRemoteView?.setImageViewResource(R.id.iv_npc_album, R.drawable.app_notification_logo)
        mNotificationManager?.notify(mNotificationId, mNotification)
    }

    fun prepareError() {
        dismissInfoDialog()
        mTv_aom_musicInfo.text = resources.getString(R.string.string_fragment_music_info_empty)
        mTv_aom_musicInfo.isSelected = false
        mOnlineMusicId = null
        mRrpv_aom.error()
        showToast(resources.getString(R.string.string_prepare_fail))
    }

    fun onMediaPlayerPrepared() {
        dismissInfoDialog()
        mTv_aom_musicInfo.text = "${mOnlineMusicId!!.name} - ${mOnlineMusicId!!.singer}"
        mTv_aom_musicInfo.isSelected = true
        mRrpv_aom.startAnim()
        mIv_aom_play.setImageResource(R.drawable.img_pause)
        if(mOnlineMusicId != null){
            findOnlineLrcFragment().loadLrcData(mOnlineMusicId!!.id)
        }
        mRemoteView?.setImageViewResource(R.id.iv_npc_playorpause, R.drawable.img_pause)
        mRemoteView?.setTextColor(R.id.tv_npc_songinfo, Color.GREEN)
        mRemoteView?.setTextViewText(
            R.id.tv_npc_songinfo,
            "${mOnlineMusicId!!.name} - ${mOnlineMusicId!!.singer}"
        )
        mNotificationManager?.notify(mNotificationId, mNotification)
    }

    fun handChangeNextSong(next: Boolean) {
        findOnlineMusicFragment().handChangeNextSong(next,true)
    }

    fun autoChangeNextSong(){
        findOnlineMusicFragment().handChangeNextSong(true,false)
    }

    fun onProgress(current: Int, total: Int) {
        mRrpv_aom.setProgress(current,total)
        mTv_aom_musicDuration.text =
            "${LrcUtil.formatLrcTime(current)}/${LrcUtil.formatLrcTime(total)}"
        findOnlineLrcFragment().onProgress(current,total)
    }

    fun onPlayCompletion() {
        mOnlineMusicId = null
        autoChangeNextSong()
    }

    fun onSeletedMusicId(): Boolean {
        return mOnlineMusicId != null
    }

    fun handSyncProgress(progress: Int) {
        mOnlineMusicPresenter.seekTo(progress)
    }
    fun dismissNotification() {
        MediaPause()
        mNotificationManager?.cancel(mNotificationId)
    }

    fun handChangeNextSongError() {
        showToast(resources.getString(R.string.string_search_list_empty))
    }

    fun dismissInfoDialog() {
        mInfoDialog.dismiss()
    }

    inner class ComeInPhoneReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            var manager = context.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
            val callState = manager.callState
            if (callState == TelephonyManager.CALL_STATE_RINGING) {
                mIsRingLing = true
                onStop()
            } else if (callState == TelephonyManager.CALL_STATE_IDLE) {
                mIsRingLing = false
                onResume()
            }
        }
    }

    inner class NotificationActionReceiver : BroadcastReceiver() {
        override fun onReceive(p0: Context?, i: Intent) {
            dealAction(i.action)
        }

        private fun dealAction(action: String?) {
            action?.let {
                when (it) {
                    NotificationPlayStatus.STATUS_PREV -> {
                        handChangeNextSong(false)
                    }

                    NotificationPlayStatus.STATUS_PLAY_OR_PAUSE -> {
                        onPlayClick()
                    }

                    NotificationPlayStatus.STATUS_NEXT -> {
                        handChangeNextSong(true)
                    }

                    NotificationPlayStatus.STATUS_CLOSE -> {
                        dismissNotification()
                    }

                    else -> {

                    }
                }
            }
        }
    }

}